var config = require("./data/config.json");
var cdf = require("./data/cofCDFs.json");
var pktSizeCDF = require("./data/packetSizeCDF.json");

var fs = require("fs");

var getPattern = require("./getPattern.js");
var getRandomCDF = require("./getRandomCDF.js");

function generateInfo(cdf) {
	var result = []; //用于存储cof信息构成的行
	var r_ports = {}; //用于存储reducer对应的端口号

	var cofInfo = [];
	var cofNum = config.cofNum;
	var pre = 0;
	var flag = false;

	for(var i = 0; i < cofNum; i++) {
		var temp = []; //用于存储本条coflow中的信息。
		var cofSize = 0; //用于存储coflow的总大小。
		
		//根据gap的cdf分布随机生成cof的开始时间间隔，startTime是指该coflow与上一条coflow之间的间隔
		var startTime = (flag == false) ? 0 : getRandomCDF(cdf.gapCDF);
		flag = true;

		//根据coflow中流数目的分布随机生成流数目
		var flowNum = Math.ceil(getRandomCDF(cdf.widthCDF) * config.hosts);
		//console.log(flowNum);

		temp.push(Math.floor(startTime));
		temp.push(flowNum);

		//随机生成源目节点号，以及源目port
		//var trafficPattern = getPattern(flowNum, config.hosts, r_ports);
		//temp = temp.concat(trafficPattern);
		
		//根据流gap的CDF分布，随机生成coflow中每条流的开始时间,以及前n个报文的平均大小
		//按照文章coda中所说，spark中的coflow子流的到达时间间隔服从0~100ms的均匀分布，仿真平台要用微秒做单位
		var aveSize_array = [];
		var fGap = [];
		var fflag = false;
		for(var j = 0; j < flowNum; j++) {
			var fStartT = (fflag == false) ? 0 : Math.floor(Math.random() * 100000);
			fflag = true;

			fGap.push(Math.floor(fStartT));

			var psize = 0;
			for(var k = 0; k < config.packetNum_test; k++) {
				psize += getRandomCDF(pktSizeCDF);
			}

			var aveSize = Math.floor(psize / config.packetNum_test);

			aveSize_array.push(aveSize);

			//根据aveFlowSizeCDF和skewCDF随机生成coflow子流的大小，并得到coflow总大小，根据coflow大小的优先级阈值，得到coflow的优先级。
			var aveFlowSize = getRandomCDF(cdf.aveFlowSizeCDF);
			var flowSkew = getRandomCDF(cdf.skewCDF);
			var flowSize = Math.floor(aveFlowSize + flowSkew * aveFlowSize);

			cofSize += flowSize;
		}
		
		//得到k条子流的前N个报文的平均大小的平均值。
		var cofAveNSize = 0;
		for(var j = 0; j < aveSize_array.length; j++) {
			cofAveNSize += aveSize_array[j];
		}

		//得到k条子流的平均到达时间间隔
		var flowGap = 0;
		for(var j = 0; j < flowNum; j++) {
			flowGap += fGap[j];
		}

		cofAveNSize = cofAveNSize / flowNum;
		flowGap = (flowNum == 1) ? flowGap : flowGap / (flowNum - 1);
		temp.push(cofAveNSize);
		temp.push(flowGap);
		//console.log(temp);
		
		
		//用coflow的大小制定coflow的优先级
		var threshold = config.threshold;
		var prior_ID = 0;
		for(var j = threshold.length - 1; j > 0; j--) {
			if(cofSize > threshold[j]) {
				prior_ID = j;
				break;
			}
		}

		console.log("cofSize " + i + ": " + cofSize, flowNum, prior_ID);
		temp.push(prior_ID);
		
		temp = temp.join(",");
		result.push(temp);
	}

	return result;
}

function main () {
	//生成config, 主要是生成config里的threshold(通过对阈值制定机制的讨论再做，现在用实验性的threshold).
	//TODO generateConfig();
	var result = generateInfo(cdf);
	var output = result.join("\n");
	//console.log(output);

	fs.writeFile("./data/output.csv", output, function() {
		console.log("generate cofInfo succeed");
	});
}

main();